<template>
	<view class="fill g_flex_page">
		<sp-html2pdf-render domId="pdfPreview" ref="renderRef" :showLoading="true" afterSavePDF="afterSavePDF"
			@renderOver="renderOver" :pdfFileName="pdfFileName"></sp-html2pdf-render>
		<cl-nav-bar :title="templateData.name"></cl-nav-bar>
		<view class="fill_content">
			<uni-forms ref="formRef" label-width="300" label-position="top" :model="formData">
				<view class="card_box">
					<view class="card_box_title">基本信息</view>
					<uni-forms-item name="creator" label="填报人" required
						:rules="[{ required: true, errorMessage: '填报人名称不能为空' }]">
						<!-- <uni-easyinput v-model="formData.creator" type="text" placeholder="请输入" /> -->
						<cl-autocomplete v-model="formData.creator" placeholder="请输入"
							:options="vagueQueryMap.creatorList"></cl-autocomplete>
					</uni-forms-item>
					<uni-forms-item name="creatorTel" label="填报人电话" required :rules="[
              { required: true, errorMessage: '填报人电话不能为空' },
              { pattern: /^1[3-9]\d{9}$/, errorMessage: '请输入正确电话格式' },
            ]">
						<cl-autocomplete v-model="formData.creatorTel" type="tel" placeholder="请输入"
							:options="vagueQueryMap.creatorTelList" />
					</uni-forms-item>
					<uni-forms-item name="projectModel" label="项目型号" required :rules="[
					    { required: true, errorMessage: '项目型号不能为空' },
					  ]">
						<cl-autocomplete v-model="formData.projectModel" placeholder="请输入"
							:options="vagueQueryMap.projectModelList" />
					</uni-forms-item>
					<uni-forms-item name="batchNumber" label="批次号" required :rules="[
					    { required: true, errorMessage: '批次号不能为空' },
					  ]">
						<cl-autocomplete v-model="formData.batchNumber" placeholder="请输入"
							:options="vagueQueryMap.batchNumberList" />
					</uni-forms-item>
					<uni-forms-item name="number" label="数量">
						<uni-easyinput v-model="formData.number" placeholder="请输入" type="number" />
					</uni-forms-item>
					<uni-forms-item name="agingAddress" label="老化地点" required :rules="[
					    { required: true, errorMessage: '老化地点不能为空' },
					  ]">
						<cl-autocomplete v-model="formData.agingAddress" placeholder="请输入"
							:options="vagueQueryMap.agingAddressList" />
					</uni-forms-item>
					<uni-forms-item name="startDate" label="开始时间" required :rules="[
					    { required: true, errorMessage: '开始时间不能为空' },
					  ]">
						<cl-date-picker v-model="formData.startDate" dateType='YYYY-MM-DD hh:mm'></cl-date-picker>
					</uni-forms-item>
					<uni-forms-item name="workDate" label="工时" required :rules="[
					    { required: true, errorMessage: '工时不能为空' },
							{ pattern: /^[1-9]\d*$/, errorMessage: '工时为正整数'}
					  ]">
						<uni-easyinput v-model="formData.workDate" placeholder="请输入" type="number" />
					</uni-forms-item>
					<uni-forms-item name="endDate" label="结束时间" required :rules="[
					    { required: true, errorMessage: '结束时间不能为空' },
					  ]">
						<cl-date-picker v-model="formData.endDate" dateType='YYYY-MM-DD hh:mm'
							disabled></cl-date-picker>
					</uni-forms-item>
					<uni-forms-item name="title" label="填报标题(保存后根据项目型号_批次号_时间自动生成)" required>
						<uni-easyinput v-model="formData.title" type="text" placeholder="无需输入,自动生成" disabled />
					</uni-forms-item>
				</view>
				<view class="card_box mt_40">
					<view class="card_box_title">模板信息</view>
					<uni-forms-item :label="item.label" :name="item.field_id" v-for="item in templateData.fieldList"
						:key="item.field_id" :required="item.required === 1" :rules="
              item.required === 1
                ? [{ required: true, errorMessage: `${item.label}不能为空` }]
                : []
            ">
						<uni-easyinput v-if="item.type === 'input'" v-model="formData[item.field_id]" type="text"
							:placeholder="item.placeholder" />
						<uni-easyinput v-if="item.type === 'numberInput'" v-model="formData[item.field_id]" type="digit"
							:placeholder="item.placeholder" />
						<cl-more-select-picker v-if="item.type === 'select'" v-model="formData[item.field_id]"
							:options="item.options"></cl-more-select-picker>
						<cl-date-picker v-if="item.type === 'date'" v-model="formData[item.field_id]"></cl-date-picker>
						<SelfUpload v-if="item.type === 'upImage'" v-model="formData[item.field_id]"
							:maxSize="item.maxSize" :maxLength="item.maxLength"></SelfUpload>
					</uni-forms-item>
				</view>
			</uni-forms>
		</view>
		<view class="fill_footer">
			<view class="fill_footer_btn preview_btn" @click="handlePreview">预览</view>
			<view class="fill_footer_btn save_btn" @click="handleSave">保存</view>
		</view>
	</view>
	<uni-popup ref="popupRef" type="center">
		<view class="paf_preview">
			<view class="paf_preview_content" id="pdfPreview">
				<view>
					基本信息
				</view>
				<view class="field_item" v-for="item in baseFieldList" :key="item.value">
					<view class="field_item_label">{{ item.label }}：</view>
					<view class="field_item_value">{{copyFormData[item.value]}}</view>
				</view>
				<view>
					模板信息
				</view>
				<template v-for="item in templateData.fieldList" :key="item.field_id">
					<view class="field_item" v-if="
              ['input', 'numberInput', 'date', 'select'].includes(item.type)
            ">
						<view class="field_item_label">{{ item.label }}：</view>
						<view class="field_item_value">
							{{
                Array.isArray(copyFormData[item.field_id])
                  ? copyFormData[item.field_id].join('、')
                  : copyFormData[item.field_id]
              }}
						</view>
					</view>
					<view v-else-if="item.type === 'upImage'">
						<view class="field_item_img_label">{{ item.label }}：</view>
						<img class="field_item_img_value" v-for="itm in copyFormData[item.field_id]" :key="itm.url"
							:src="itm.b64Data" mode="widthFix" />
					</view>
				</template>
			</view>
			<view class="paf_preview_bottom">
				<view class="paf_preview_bottom_btn" @click="handleSavePDF">保存为</view>
			</view>
		</view>
	</uni-popup>
</template>

<script setup>
	import {
		getUuid
	} from '../../utils/uuid'
	import {
		formatDate
	} from '../../utils'
	import {
		getCurrentInstance,
		watch,
		reactive
	} from 'vue'
	import {
		cloneDeep
	} from 'lodash'
	import {
		pathToBase64,
		getLocalFilePath,
	} from '../../uni_modules/sp-html2pdf-render/utils'

	import {
		getJsonData,
		getOrCreateDir,
		copyFile,
		removeDir,
		removeFile,
		createFillJson,
		getVagueQuery,
		setVagueQuery,
		checkImage
	} from '../../utils/file'
	const formRef = ref()
	let eventChannel = null
	const pdfFileName = ref('')
	const templateData = ref({
		name: '',
		templateId: '',
		fieldList: [],
	})
	const formData = ref({
		creator: undefined,
		creatorTel: undefined,
		title: undefined,
	})
	const tempalteDirName = ref('')
	const fillDirName = ref('')
	let type = 'add'
	let originFormData = ref({})
	const vagueQueryMap = reactive({
		creatorList: [],
		creatorTelList: [],
		projectModelList: [],
		batchNumberList: [],
		agingAddressList: []
	})
	const baseFieldList = [{
			label: '填报人',
			value: 'creator'
		},
		{
			label: '填报人电话',
			value: 'creatorTel'
		},
		{
			label: '项目型号',
			value: 'projectModel'
		},
		{
			label: '批次号',
			value: 'batchNumber'
		},
		{
			label: '数量',
			value: 'number'
		},
		{
			label: '老化地点',
			value: 'agingAddress'
		}, {
			label: '开始时间',
			value: 'startDate'
		}, {
			label: '工时',
			value: 'workDate'
		}, {
			label: '结束时间',
			value: 'endDate'
		}
	]
	onLoad(async () => {
		uni.showLoading({
			title: '数据加载中',
		})
		const instance = getCurrentInstance().proxy
		eventChannel = instance.getOpenerEventChannel()
		eventChannel.on('acceptDataFromOpenerPage', async function(data) {
			tempalteDirName.value = data.tempalteDirName
			const res = await getJsonData(
				`_doc/templateList/${tempalteDirName.value}/templateData.json`
			)
			templateData.value = JSON.parse(res.result)
			if (data.fillDirName) {
				type = 'edit'
				fillDirName.value = data.fillDirName
				const res = await getJsonData(
					`_doc/templateList/${tempalteDirName.value}/fillList/${fillDirName.value}/fillData.json`
				)
				formData.value = correct(JSON.parse(res.result))
				originFormData.value = correct(JSON.parse(res.result))
				const checkFlag = await checkImage(templateData.value, formData.value)
				if (!checkFlag) {
					uni.showToast({
						title: '图片缺失，请重新上传！',
						icon: 'none',
						mask: true
					})
				}
			} else {
				templateData.value.fieldList.forEach((item) => {
					formData.value[item.field_id] = item.defaultVal || ''
				})
			}
			const {
				creatorList = [],
					creatorTelList = [],
					projectModelList = [],
					batchNumberList = [],
					agingAddressList = [],
			} = await getVagueQuery()
			vagueQueryMap.creatorList = creatorList
			vagueQueryMap.creatorTelList = creatorTelList
			vagueQueryMap.projectModelList = projectModelList
			vagueQueryMap.batchNumberList = batchNumberList
			vagueQueryMap.agingAddressList = agingAddressList
			uni.hideLoading()
			
		})
		uni.hideLoading()
	})

	// 判断是否为时间字符串
	const checkDateRegex = (str) => {
		let dateRegList = [
			/^\d{4}$/,
			/^\d{4}-\d{2}$/,
			/^\d{4}-\d{2}-\d{2}/,
			/^\d{4}-\d{2}-\d{2} \d{2}$/,
			/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/,
			/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/
		];
		for (let i = 0; i < dateRegList.length; i++) {
			if (dateRegList[i].test(str)) {
				return true;
			}
		}
		return false;
	}

	// 矫正字段值
	const correct = (fillData) => {
		console.log(fillData, 'fillData');
		let newFillData = {
			...fillData
		}
		templateData.value.fieldList.forEach(item => {
			let val = newFillData[item.field_id];
			if (item.type === 'input' && typeof val !== 'string') {
				newFillData[item.field_id] = item.defaultVal
			}
			if (item.type === 'numberInput' && typeof val !== 'string') {
				newFillData[item.field_id] = item.defaultVal
			}
			if (item.type === 'select' && !Array.isArray(val)) {
				newFillData[item.field_id] = item.defaultVal
			}
			if (item.type === 'upImage' && !Array.isArray(val)) {
				newFillData[item.field_id] = item.defaultVal
			}
			if (item.type === 'date') {
				if (typeof val !== 'string' || !checkDateRegex(val)) {
					newFillData[item.field_id] = item.defaultVal
				}
			}
		})
		console.log(newFillData);
		return newFillData
	}

	// 保存
	const handleSave = async () => {
		// 校验
		await formRef.value.validate()
		uni.showLoading({
			title: '数据保存中',
			mask: true,
		})
		// 填报标题由项目型号 + 批次号 + 开始时间生成
		formData.value.title =
			`${formData.value.projectModel}_${formData.value.batchNumber}_${formData.value.startDate}`
		if (type === 'edit') {
			// 如果是编辑添加编辑时间
			formData.value.editTime = formatDate()
		} else {
			//如果新增则添加创建时间与填报id
			formData.value.creatTime = formatDate()
			formData.value.fillId = getUuid()
		}
		let fillFileName = ''
		if (formData.value.editTime) {
			fillFileName = `${formData.value.fillId}␟${formData.value.editTime}␟${formData.value.title}`
		} else {
			fillFileName = `${formData.value.fillId}␟${formData.value.creatTime}␟${formData.value.title}`
		}
		// 新建填报图片文件夹 （无论之前有没有图片的文件夹，都要执行该操作，即使之前已存在也不会影响存在的文件夹数据）
		await getOrCreateDir(
			`_doc/templateList/${tempalteDirName.value}/fillList/${fillFileName}/images`,
			true
		)
		// 对图片数据进行单独处理，最新上传的图片还是临时地址，需要转存到对应文件夹
		const imageIds = templateData.value.fieldList
			.filter((item) => item.type === 'upImage')
			.map((item) => item.field_id)
		// 拿到所有图片字段
		for (const i of imageIds) {
			const curImageList = formData.value[i].map(item => {
				return copyFile(
					item.url,
					`_doc/templateList/${tempalteDirName.value}/fillList/${fillFileName}/images`,
					item.name
				)
			})
			await Promise.all(curImageList)
			// 等文件迁移结束后再校验所有图片的url
			formData.value[i] = formData.value[i].map((item) => {
				if (item.isNew) {
					item.isNew = false
				}
				item.url =
					`_doc/templateList/${tempalteDirName.value}/fillList/${fillFileName}/images/${item.name}`
				return item
			})
		}
		createFillJson(
				tempalteDirName.value,
				fillFileName,
				formData.value
			)
			.then(() => {
				setTimeout(() => {
					uni.showToast({
						title: '保存成功！',
						icon: 'success',
						mask: true,
						success: () => {
							if (type === 'edit') {
								removeDir(
									`_doc/templateList/${tempalteDirName.value}/fillList/${fillDirName.value}`
								)
							}
							// 删除无用图片
							// contrastAndDel()
							// 判断是否将固定字段添加到json里保存，这样后续可以支持模糊查询
							let isUpdate = false
							if (vagueQueryMap.creatorList.every(item => item !== formData
									.value.creator)) {
								vagueQueryMap.creatorList.push(formData.value.creator)
								isUpdate = true
							}
							if (vagueQueryMap.creatorTelList.every(item => item !==
									formData.value.creatorTel)) {
								vagueQueryMap.creatorTelList.push(formData.value
									.creatorTel)
								isUpdate = true
							}
							if (vagueQueryMap.projectModelList.every(item => item !==
									formData.value.projectModel)) {
								vagueQueryMap.projectModelList.push(formData.value
									.projectModel)
								isUpdate = true
							}
							if (vagueQueryMap.batchNumberList.every(item => item !==
									formData.value.batchNumber)) {
								vagueQueryMap.batchNumberList.push(formData.value
									.batchNumber)
								isUpdate = true
							}
							if (vagueQueryMap.agingAddressList.every(item => item !==
									formData.value.agingAddress)) {
								vagueQueryMap.agingAddressList.push(formData.value
									.agingAddress)
								isUpdate = true
							}
							if (isUpdate) {
								setVagueQuery(vagueQueryMap)
							}
							setTimeout(() => {
								uni.navigateBack({
									success: () => {
										eventChannel.emit(
											'acceptDataFromOpenedPage'
											)
									},
								})
							}, 500)
						},
					})
				}, 2000)
			})
			.catch(() => {
				uni.showToast({
					title: '保存失败！',
					icon: 'error'
				})
			})
	}

	// 预览
	const renderRef = ref()
	const popupRef = ref()
	const copyFormData = ref({})
	const handlePreview = async () => {
		await formRef.value.validate()
		uni.showLoading({
			title: '数据加载中...'
		})
		const checkFlag = await checkImage(templateData.value, formData.value)
		if (!checkFlag) {
			uni.showToast({
				title: '图片缺失，请重新上传！',
				icon: 'none',
				mask: true
			})
		}
		try {
			await toB64Show()
			setTimeout(() => {
				uni.hideLoading()
				popupRef.value.open()
			}, 500)
		} catch (error) {
			uni.showToast({
				title: '数据异常，请重试',
				icon: 'none',
				mask: true,
			})
		}
	}

	const demoImg = ref('')
	const renderOver = (e) => {
		demoImg.value = e
	}
	// 下载之后
	const afterSavePDF = (e) => {
		popupRef.value.close()
	}

	// pdf保存
	const handleSavePDF = async () => {
		// 因为电脑不识别空格跟冒号的文件名
		let newDate = formData.value.startDate.replace(' ', '_').replace(':', '-')
		pdfFileName.value = `${formData.value.projectModel}_${formData.value.batchNumber}_${newDate}`
		renderRef.value.h2pRenderDom()
	}

	// 图片转b64格式展示
	const toB64Show = async () => {
		let localCopyFormData = cloneDeep(formData.value)
		let imgFieldIds = templateData.value.fieldList
			.filter((item) => item.type === 'upImage')
			.map((item) => item.field_id)
		for (const fieldId of imgFieldIds) {
			for (const imgItem of localCopyFormData[fieldId] || []) {
				imgItem.b64Data = await pathToBase64(getLocalFilePath(imgItem.url))
			}
		}
		copyFormData.value = localCopyFormData
	}

	// 对比并删除图片（如果将非图片字段改为图片字段，则会出现图片删除不了的问题）
	const contrastAndDel = () => {
		let imageIds = templateData.value.fieldList
			.filter((item) => item.type === 'upImage')
			.map((item) => item.field_id)
		imageIds.forEach((item) => {
			let newFormDataImageNames = formData.value[item].map((itm) => itm.name);
			(originFormData.value[item] || [])
			.filter((itm) => !newFormDataImageNames.includes(itm.name))
				.map((itm) => removeFile(itm.url))
		})
	}
	// 根据开始时间和工时计算结束时间
	const calculateEndTime = (startTime, workingHours) => {
		// 首先将开始时间字符串转换为 Date 对象
		const startDate = new Date(startTime.replace(' ', 'T') + ':00');
		// 检查输入的工时是否为有效的正整数
		// if (typeof workingHours !== 'number' || workingHours <= 0 || !Number.isInteger(workingHours)) {
		// 	throw new Error('工时必须是正整数');
		// }
		// 在开始时间的基础上加上工时对应的毫秒数
		const endTimestamp = startDate.getTime() + workingHours * 60 * 60 * 1000;
		// 根据新的时间戳创建一个新的 Date 对象
		const endDate = new Date(endTimestamp);
		// 格式化结束时间，使其与开始时间格式一致
		const year = endDate.getFullYear();
		const month = String(endDate.getMonth() + 1).padStart(2, '0');
		const day = String(endDate.getDate()).padStart(2, '0');
		const hour = String(endDate.getHours()).padStart(2, '0');
		const min = String(endDate.getMinutes()).padStart(2, '0');
		return `${year}-${month}-${day} ${hour}:${min}`;
	}
	// 监听开始时间与结束时间
	watch(() => [formData.value.startDate, formData.value.workDate], (newV) => {
		const [startDate, workDate] = newV
		if (startDate && workDate) {
			const endDate = calculateEndTime(startDate, workDate)
			formData.value.endDate = endDate
		} else {
			formData.value.endDate = ''
		}
	}, {
		deep: true,
		immediate: true
	})
</script>
<style lang="scss" scoped>
	.fill {
		&_content {
			padding: 20rpx;
			box-sizing: border-box;
			flex: 1;
			overflow-y: auto;

			.card_box {
				padding: 20rpx;
				border-radius: 12rpx;
				background-color: #fff;

				&_title {
					margin: 20rpx 0;
					font-size: 32rpx;
					font-weight: bold;
				}
			}
		}

		&_footer {
			padding: 20rpx 60rpx;
			display: flex;
			box-shadow: 0px 4px 16px 0px rgba(17, 17, 26, 0.05),
				0px 8px 32px 0px rgba(17, 17, 26, 0.05);
			width: 100%;
			box-sizing: border-box;
			background-color: #fff;

			&_btn {
				padding: 20rpx;
				flex: 1;
				text-align: center;
				color: #fff;
				border-radius: 40rpx;
				background-color: $uni-color-primary;
			}

			.preview_btn {
				margin-right: 60rpx;
				background-color: $uni-text-color-grey;
			}
		}
	}

	.paf_preview {
		position: relative;
		box-sizing: border-box;
		background-color: #fff;
		width: 90vw;
		max-height: 80vh;
		overflow-y: auto;
		border-radius: 10rpx;

		&_content {
			width: 1000rpx;
			margin: 20rpx 0;
			padding: 40rpx;
			height: max-content;
			overflow-y: auto;

			.field_item {
				margin: 20rpx 0;
				display: flex;
				align-items: center;

				&_label {
					font-weight: bold;
					flex-shrink: 0;
					width: 8rem;
					text-align: right;
				}

				&_right {
					margin-left: 40rpx;
				}
			}

			.field_item_img {
				&_label {
					font-weight: bold;
					flex-shrink: 0;
					width: 8rem;
					text-align: right;
				}

				&_value {
					margin-top: 20rpx;
					width: 100%;
					page-break-before: always;
					/* 强制在图片前分页 */
					page-break-after: always;
					/* 强制在图片后分页 */
					page-break-inside: avoid;
					/* 确保图片本身不被分割 */
					text-align: center;
					/* 图片居中显示 */
					padding: 20px;
				}
			}
		}

		&_bottom {
			padding: 20rpx;
			position: sticky;
			bottom: 0;
			left: 0;
			box-sizing: border-box;
			width: 100%;
			background-color: #fff;

			&_btn {
				padding: 20rpx;
				box-sizing: border-box;
				margin: auto;
				width: 60%;
				text-align: center;
				border-radius: 40rpx;
				color: #fff;
				background-color: $uni-color-primary;
			}
		}
	}
</style>